package com.zyao89.view.zloading.circle;

import com.zyao89.view.zloading.ZLoadingBuilder;
import com.zyao89.view.zloading.util.NumCalcUtil;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.ColorFilter;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * PacManBuilder
 *
 * @author jjy
 * @since 2021-03-22
 */
public class PacManBuilder extends ZLoadingBuilder {
    private static final String TAG = "Zloading PacManBuilder";

    // 最终阶段
    private static final int FINAL_STATE = 9;
    private static final int MAX_MOUTH_ANGLE = 45;
    private long mDurationTime = 333;
    private Paint mFullPaint;
    private RectFloat mOuterCircleRectF;
    private int mMouthAngle;
    private float mMoveDistance;

    // 当前动画阶段
    private int mCurrAnimatorState = 0;
    private int HorizontalAngle;
    private float mMaxMoveRange;
    private float mLastMoveDistance;
    private float mDefaultStartMoveX;
    private Arc mArc;

    @Override
    protected void initParams(Context context, Color color) {
        mArc = new Arc();
        float outR = getAllSize();
        float inR = outR * 0.7f;
        mMaxMoveRange = NumCalcUtil.add(getIntrinsicWidth(), 2 * inR);

        // 移动距离范围
        initPaint(color);

        // 圆范围
        mMouthAngle = MAX_MOUTH_ANGLE;

        // 嘴度数
        HorizontalAngle = 0;

        // 水平翻转度数
        mDefaultStartMoveX = -mMaxMoveRange * 0.5f;

        // 默认偏移量
        mMoveDistance = 0;

        // 移动距离
        mOuterCircleRectF = new RectFloat(NumCalcUtil.subtract(getViewCenterX(), inR), NumCalcUtil.subtract(getViewCenterY(), inR), NumCalcUtil.add(getViewCenterX(), inR), NumCalcUtil.add(getViewCenterY(), inR));
    }

    private void initPaint(Color color) {
        mFullPaint = new Paint();
        mFullPaint.setStyle(Paint.Style.FILL_STYLE);
        mFullPaint.setColor(color);
        mFullPaint.setDither(true);
        mFullPaint.setFilterBitmap(true);
        mFullPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        mFullPaint.setStrokeJoin(Paint.Join.ROUND_JOIN);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.save();
        canvas.translate(NumCalcUtil.add(mDefaultStartMoveX, mMoveDistance), 0);
        canvas.rotate(HorizontalAngle, getViewCenterX(), getViewCenterY());
        mArc.setArc(mMouthAngle, 360 - mMouthAngle * 2, true);
        canvas.drawArc(mOuterCircleRectF, mArc, mFullPaint);
        canvas.restore();
    }

    @Override
    protected void setAlpha(int alpha) {
        mFullPaint.setAlpha(alpha);
    }

    @Override
    protected void prepareStart(AnimatorValue floatValueAnimator) {
        mDurationTime = ceil(getAnimationDuration() * 0.3);

        floatValueAnimator.setDuration(mDurationTime);
    }

    @Override
    protected void prepareEnd() {

    }

    @Override
    protected void computeUpdateValue(AnimatorValue animation, /*@FloatRange(from = 0.0, to = 1.0) */float animatedValue) {
        int half = FINAL_STATE / 2 + 1;
        float step = mMaxMoveRange / half;
        if (mCurrAnimatorState < half) {
            HorizontalAngle = 0;
            mMoveDistance = NumCalcUtil.add(mLastMoveDistance, step * animatedValue);
        } else {
            HorizontalAngle = 180;
            mMoveDistance = NumCalcUtil.subtract(mLastMoveDistance, step * animatedValue);
        }
        if (mCurrAnimatorState % 2 == 0) {
            mMouthAngle = (int) (MAX_MOUTH_ANGLE * animatedValue) + 5;
        } else {
            mMouthAngle = (int) (MAX_MOUTH_ANGLE * NumCalcUtil.subtract(1, animatedValue)) + 5;
        }
    }

    @Override
    public void onRepeat(Animator animator) {
        if (++mCurrAnimatorState > FINAL_STATE) {

            // 还原到第一阶段
            mCurrAnimatorState = 0;
        }

        // 矫正
        int half = FINAL_STATE / 2 + 1;
        float stepRange = mMaxMoveRange / half;
        if (mCurrAnimatorState < half) {
            mLastMoveDistance = stepRange * mCurrAnimatorState;
        } else {
            mLastMoveDistance = stepRange * (half - mCurrAnimatorState % half);
        }
    }

    @Override
    protected void setColorFilter(ColorFilter colorFilter) {
        mFullPaint.setColorFilter(colorFilter);
    }

}
